home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / corprt3.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  325 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* 
  18.  *     corimg3 -
  19.  *        This contains generic corimg3 and sproof3 stuff.  This color
  20.  *    Correction technique is for single angle color screening. 
  21.  *
  22.  *                Paul Haeberli - 1989
  23.  *
  24.  *    use corone3(r,g,b,cr,cg,cb)
  25.  *    and sproof3(r,g,b,cr,cg,cb)  in the simplest case.
  26.  *
  27.  *
  28.  *    exports
  29.  *
  30.     void corrow3(rbuf,gbuf,bbuf,n)
  31.     void corone3(r,g,b,cr,cg,cb)
  32.     void sproofrow3(rbuf,gbuf,bbuf,n)
  33.     void sproof3(r,g,b,sr,sg,sb)
  34.  *
  35.  */
  36. #include "stdio.h"
  37. #include "math.h"
  38. #include "vect.h"
  39. #include "swop.h"
  40.  
  41. float flerp();
  42.  
  43. static void setprinter();
  44. void corone3();
  45. void sproof3();
  46.  
  47. #define EPSILON        (0.0001)
  48. #define NRAYS         (6*TABSIZE)
  49. #define TABSIZE       (6*256)
  50. static vect tabc, tabm, taby;
  51. static vect tabr, tabg, tabb;
  52. static float tab[TABSIZE][3];
  53. static float cmin[TABSIZE];
  54. static float cmax[TABSIZE];
  55. static int corfirsted;
  56. static int spfirsted;
  57.  
  58. static maketable()
  59. {
  60.     float h, s, v;
  61.     float r, g, b;
  62.     float sr, sg, sb;
  63.     float min, max, chroma;
  64.     int i, tabi;
  65.  
  66.     setprinter();
  67.     for(i=0; i<TABSIZE; i++) 
  68.         tab[i][0] = -1000.0;
  69.     for(i=0; i<NRAYS; i++) {
  70.     h = i/(NRAYS-1.0);
  71.     hsv_to_rgb(h,1.0,1.0,&r,&g,&b);
  72.     sproof3(r,g,b,&sr,&sg,&sb);
  73.     rgb_to_hsv(sr,sg,sb,&h,&s,&v);
  74.     min = max = sr;
  75.     if(sg<min)
  76.        min = sg;
  77.     if(sg>max)
  78.        max = sg;
  79.     if(sb<min)
  80.        min = sb;
  81.     if(sb>max)
  82.        max = sb;
  83.     tabi = TABSIZE*h;
  84.     if(tabi == TABSIZE)
  85.        tabi = 0;
  86.     cmin[tabi] = min;
  87.     cmax[tabi] = max;
  88.     tab[tabi][0] = r;
  89.     tab[tabi][1] = g;
  90.     tab[tabi][2] = b;
  91.     }
  92.     for(i=0; i<TABSIZE; i++) {
  93.         if(tab[i][0]<=-1000.0) {
  94.         fprintf(stderr,"corimg3: bad\n");
  95.     }
  96.     }
  97. }
  98.  
  99. static float clamp(f)
  100. float f;
  101. {
  102.     if(f<0.0)
  103.     return 0.0;
  104.     else if(f>1.0)
  105.     return 1.0;
  106.     else
  107.     return f;
  108. }
  109.  
  110. void corrow3(rbuf,gbuf,bbuf,n)
  111. short *rbuf;
  112. short *gbuf;
  113. short *bbuf;
  114. int n;
  115. {
  116.     float cr, cg, cb;
  117.     short lr, lg, lb;
  118.     short ir, ig, ib;
  119.  
  120.     lr = lg = lb = -1000;
  121.     while(n--) {
  122.     if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
  123.         lr = *rbuf;
  124.         lg = *gbuf;
  125.         lb = *bbuf;
  126.         corone3(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
  127.         ir = cr*255.0+0.5;
  128.         ig = cg*255.0+0.5;
  129.         ib = cb*255.0+0.5;
  130.     }
  131.     *rbuf++ = ir;
  132.     *gbuf++ = ig;
  133.     *bbuf++ = ib;
  134.     }
  135. }
  136.  
  137. void corone3(r,g,b,cr,cg,cb)
  138. float r, g, b;
  139. float *cr, *cg, *cb;
  140. {
  141.     float min, max;
  142.     float h, s, v;
  143.     float tr, tg, tb;
  144.     float chroma, mag;
  145.     float white, cscale;
  146.     int tabi;
  147.     float tabmax, tabmin;
  148.  
  149.     if(!corfirsted) {
  150.     maketable();
  151.     corfirsted = 1;
  152.     }
  153.     min = max = r;
  154.     if(g<min)
  155.        min = g;
  156.     if(g>max)
  157.        max = g;
  158.     if(b<min)
  159.        min = b;
  160.     if(b>max)
  161.        max = b;
  162.     chroma = max-min;
  163.     if(chroma<EPSILON) {
  164.     *cr = r;
  165.     *cg = g;
  166.     *cb = b;
  167.     } else {
  168.     white = min/max;
  169.     rgb_to_hsv(r,g,b,&h,&s,&v);
  170.     tabi = TABSIZE*h;
  171.     if(tabi == TABSIZE)
  172.        tabi = 0;
  173.     tabmax = cmax[tabi];
  174.     tr = tab[tabi][0]/tabmax;
  175.     tg = tab[tabi][1]/tabmax;
  176.     tb = tab[tabi][2]/tabmax;
  177.     tr = flerp(tr,1.0,white);
  178.     tg = flerp(tg,1.0,white);
  179.     tb = flerp(tb,1.0,white);
  180.     *cr = clamp(max*tr);
  181.     *cg = clamp(max*tg);
  182.     *cb = clamp(max*tb);
  183.     }
  184. }
  185.  
  186. void sproofrow3(rbuf,gbuf,bbuf,n)
  187. unsigned short *rbuf, *gbuf, *bbuf;
  188. int n;
  189. {
  190.     float cr, cg, cb;
  191.     short lr, lg, lb;
  192.     short ir, ig, ib;
  193.  
  194.     lr = lg = lb = -1000;
  195.     while(n--) {
  196.     if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
  197.         lr = *rbuf;
  198.         lg = *gbuf;
  199.         lb = *bbuf;
  200.         sproof3(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
  201.         ir = cr*255.0+0.5;
  202.         ig = cg*255.0+0.5;
  203.         ib = cb*255.0+0.5;
  204.     }
  205.     *rbuf++ = ir;
  206.     *gbuf++ = ig;
  207.     *bbuf++ = ib;
  208.     }
  209. }
  210.  
  211. void sproof3(r,g,b,sr,sg,sb)
  212. float r, g, b;
  213. float *sr, *sg, *sb;
  214. {
  215.     float fc, fm, fy;
  216.     float min, max;
  217.     float white, chroma, p;
  218.     float val;
  219.     int bits;
  220.     vect col;
  221.  
  222.     if(!spfirsted) {
  223.     setprinter();
  224.     spfirsted = 1;
  225.     }
  226.     fc = 1.0-r;
  227.     fm = 1.0-g;
  228.     fy = 1.0-b;
  229.     bits = 0;
  230.     max = min = fc;
  231.     if(fc>fm) {
  232.     if(fc>fy) {
  233.         bits |= (1<<0);
  234.         max = fc;
  235.     } else {
  236.         bits |= (1<<2);
  237.         max = fy;
  238.     }
  239.     if(fm<fy) {
  240.         bits |= (1<<1);
  241.         min = fm;
  242.     } else {
  243.         bits |= (1<<2);
  244.         min = fy;
  245.     }
  246.     } else {
  247.     if(fm>fy) {
  248.         bits |= (1<<1);
  249.         max = fm;
  250.     } else {
  251.         bits |= (1<<2);
  252.         max = fy;
  253.     }
  254.     if(fc<fy) {
  255.         bits |= (1<<0);
  256.         min = fc;
  257.     } else {
  258.         bits |= (1<<2);
  259.         min = fy;
  260.     }
  261.     }
  262.     white = 1.0-max;
  263.     chroma = max-min;
  264.     if(chroma<EPSILON) {
  265.     val = 1.0-min;
  266.     *sr = val;
  267.     *sg = val;
  268.     *sb = val;
  269.     } else {
  270.     if((bits&(1<<0)) == 0) {
  271.         p = (fc-min)/chroma;
  272.         if(fm == max) 
  273.         vlerp(&tabm,&tabb,&col,p);
  274.         else
  275.         vlerp(&taby,&tabg,&col,p);
  276.     } else if((bits&(1<<1)) == 0) {
  277.         p = (fm-min)/chroma;
  278.         if(fy == max)  {
  279.         vlerp(&taby,&tabr,&col,p);
  280.         } else {
  281.         vlerp(&tabc,&tabb,&col,p);
  282.         }
  283.     } else if((bits&(1<<2)) == 0) {
  284.         p = (fy-min)/chroma;
  285.         if(fc == max) 
  286.         vlerp(&tabc,&tabg,&col,p);
  287.         else
  288.         vlerp(&tabm,&tabr,&col,p);
  289.     } else {
  290.         fprintf(stderr,"sproof3: bad poop\n");
  291.         exit(1);
  292.     }
  293.     vscale(&col,chroma);
  294.     col.x += white;
  295.     col.y += white;
  296.     col.z += white;
  297.     *sr = col.x;
  298.     *sg = col.y;
  299.     *sb = col.z;
  300.     }
  301. }
  302.  
  303. static void setprinter()
  304. {
  305.     tabc.x = ct3[CYA][0];
  306.     tabc.y = ct3[CYA][1];
  307.     tabc.z = ct3[CYA][2];
  308.     tabm.x = ct3[MAG][0];
  309.     tabm.y = ct3[MAG][1];
  310.     tabm.z = ct3[MAG][2];
  311.     taby.x = ct3[YEL][0];
  312.     taby.y = ct3[YEL][1];
  313.     taby.z = ct3[YEL][2];
  314.  
  315.     tabb.x = ct3[BLU][0];
  316.     tabb.y = ct3[BLU][1];
  317.     tabb.z = ct3[BLU][2];
  318.     tabg.x = ct3[GRE][0];
  319.     tabg.y = ct3[GRE][1];
  320.     tabg.z = ct3[GRE][2];
  321.     tabr.x = ct3[RED][0];
  322.     tabr.y = ct3[RED][1];
  323.     tabr.z = ct3[RED][2];
  324. }
  325.